#include "pch.h"
#include "FpString.h"

#include <cstring>

FpString::FpString()
{
	str = new char[1];
	str[0] = '\0';
	len = 0;
}

FpString::FpString(const FpString& newStr)
{
	if (this == &newStr)
	{
		return;
	}

	int newStrLen = newStr.length();
	str = new char[newStrLen + 1];
	::memcpy(str, newStr.pointer(), newStrLen);
	str[newStrLen] = '\0';
	len = newStrLen;
}

FpString::FpString(const char* charStr)
{
	int newStrLen = strlen(charStr);
	str = new char[newStrLen + 1];
	::memcpy(str, charStr, newStrLen);
	str[newStrLen] = '\0';
	len = newStrLen;
}

FpString::~FpString()
{
	delete[]str;
}

FpString& FpString::operator=(const FpString& newStr)
{
	if (this == &newStr)
		return *this;

	delete str;
	int newStrLen = newStr.length();
	str = new char[newStrLen + 1];
	::memcpy(str, newStr.pointer(), newStrLen);
	str[newStrLen] = '\0';
	len = newStrLen;
	return *this;
}

FpString& FpString::operator=(const char* newStr)
{
	delete str;
	int newStrLen = ::strlen(newStr);
	str = new char[newStrLen + 1];
	::memcpy(str, newStr, newStrLen);
	str[newStrLen] = '\0';
	len = newStrLen;
	return *this;
}

char* FpString::pointer() const
{
	return str;
}

int FpString::length() const
{
	return len;
}

FpString& FpString::operator+=(const FpString& newStr)
{
	int newStrLen = newStr.length();
	if (newStrLen > 0)
	{
		int currStrNewLen = len + newStrLen;
		char* newCharStr = new char[currStrNewLen + 1];
		if (newCharStr)
		{
			strcpy(newCharStr, str);
			strcat(newCharStr, newStr.pointer());

			delete str;
			str = newCharStr;
			len = currStrNewLen;
		}
		else
		{
			throw "NoEnoughMemoryException";
		}
	}
	return *this;
}

FpString& FpString::operator+=(const char* rightCharStr)
{
	int newStrLen = strlen(rightCharStr);
	if (newStrLen > 0)
	{
		int currStrNewLen = len + newStrLen;
		char* newCharStr = new char[currStrNewLen + 1];
		if (newCharStr)
		{
			strcpy(newCharStr, str);
			strcat(newCharStr, rightCharStr);

			delete str;
			str = newCharStr;
			len = currStrNewLen;
		}
		else
		{
			throw "NoEnoughMemoryException";
		}
	}
	return *this;
}

char& FpString::operator[](int index)
{
	return str[index];
}

const char& FpString::operator[](int index) const
{
	return str[index];
}

FpString::operator char* ()
{
	return str;
}

char* FpString::c_str() const
{
	return str;
}

bool FpString::empty() const
{
	return (len == 0);
}

bool operator==(const FpString& leftStr, const FpString& rightStr)
{
	if (leftStr.pointer() == rightStr.pointer())
		return true;
	return (!strcmp(leftStr.pointer(), rightStr.pointer()));
}

bool operator==(const FpString& leftStr, const char* rightCharStr)
{
	if (leftStr.pointer() == rightCharStr)
		return true;
	return (!strcmp(leftStr.pointer(), rightCharStr));
}

bool operator==(const char* leftCharStr, const FpString& rightStr)
{
	return operator==(rightStr, leftCharStr);
}

bool operator!=(const FpString& leftStr, const FpString& rightStr)
{
	return !(operator==(leftStr, rightStr));
}

bool operator!=(const FpString& leftStr, const char* rightCharStr)
{
	return !(operator==(leftStr, rightCharStr));
}

bool operator!=(const char* leftCharStr, const FpString& rightStr)
{
	return !(operator==(rightStr, leftCharStr));
}

bool operator>(const FpString& leftStr, const FpString& rightStr)
{
	if (leftStr.pointer() == rightStr.pointer())
		return false;
	return (strcmp(leftStr.pointer(), rightStr.pointer()) > 0);
}


bool operator>(const FpString& leftStr, const char* rightCharStr)
{
	if (leftStr.pointer() == rightCharStr)
		return false;
	return (strcmp(leftStr.pointer(), rightCharStr) > 0);
}


bool operator<(const FpString& leftStr, const FpString& rightStr)
{
	if (leftStr.pointer() == rightStr.pointer())
		return false;
	return (strcmp(leftStr.pointer(), rightStr.pointer()) < 0);
}


bool operator<(const FpString& leftStr, const char* rightCharStr)
{
	if (leftStr.pointer() == rightCharStr)
		return false;
	return (strcmp(leftStr.pointer(), rightCharStr) < 0);
}


bool operator>=(const FpString& leftStr, const FpString& rightStr)
{
	if (leftStr.pointer() == rightStr.pointer())
		return true;
	return (strcmp(leftStr.pointer(), rightStr.pointer()) >= 0);
}


bool operator>=(const FpString& leftStr, const char* rightCharStr)
{
	if (leftStr.pointer() == rightCharStr)
		return true;
	return (strcmp(leftStr.pointer(), rightCharStr) >= 0);
}


bool operator<=(const FpString& leftStr, const FpString& rightStr)
{
	if (leftStr.pointer() == rightStr.pointer())
		return true;
	return (strcmp(leftStr.pointer(), rightStr.pointer()) <= 0);
}


bool operator<=(const FpString& leftStr, const char* rightCharStr)
{
	if (leftStr.pointer() == rightCharStr)
		return true;
	return (strcmp(leftStr.pointer(), rightCharStr) <= 0);
}


FpString operator+(const FpString& leftStr, const FpString& rightStr)
{
	int leftStrLen = leftStr.length();
	int rightStrLen = rightStr.length();
	FpString str;

	char* newCharStr = new char[leftStrLen + rightStrLen + 1];
	if (newCharStr)
	{
		strcpy(newCharStr, leftStr.pointer());
		strcat(newCharStr, rightStr.pointer());
		str = newCharStr;
		delete[]newCharStr;
		return str;
	}
	else
	{
		throw "NoEnoughMemoryException";
	}
}


FpString operator+(const FpString& leftStr, const char* rightCharStr)
{
	int leftStrLen = leftStr.length();
	int rightStrLen = strlen(rightCharStr);
	FpString str;

	char* newCharStr = new char[leftStrLen + rightStrLen + 1];
	if (newCharStr)
	{
		strcpy(newCharStr, leftStr.pointer());
		strcat(newCharStr, rightCharStr);
		str = newCharStr;
		delete[]newCharStr;
		return str;
	}
	else
	{
		throw "NoEnoughMemoryException";
	}
}

ostream& operator<<(ostream& os, const FpString& ccStr)
{
	os << ccStr.str;
	return os;
}


istream& operator>>(istream& is, FpString& ccStr)
{
	ccStr.str = new char[128];		// I am sorry, but I don't know the exact buffer size, 128 is just thought just now.
	is >> ccStr.str;
	ccStr.len = strlen(ccStr.str);

	return is;
}
